package com.huike.framework.security.filter;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.huike.common.core.domain.model.LoginUser;
import com.huike.common.utils.SecurityUtils;
import com.huike.common.utils.StringUtils;
import com.huike.framework.web.service.TokenService;

/**
 *
 * <p>该 过滤器 被添加到security 类似过滤器链中，当前过滤器 优先级应该比较高，会先执行 <p/>
 * 请求都会  会被 security 拦截或过滤   会判断 用户请求的资源 是否 受保护， 是会对用户认证，否应该是放行
 *  <br><br/>
 *
 *  <p>1、 请求 带token  根据token 验证是否 存在（在缓存中是否有对应用户信息）
 *      有 判断信息在缓存中的 时效是否块过期 是 对其 续期，否 不操作，
 *      然后 户权限 信息？？？ 设置用户的token 设置权限？？？？ 这些操作相当于 第一个过滤器
 *
 *      <p/>
 *
 *  <p>2、 请求 未带token  不处理 token信息 和用户权限相关信息    <p/>
 *
 *
 * 
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private TokenService tokenService;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        //根据用户信息 获取其令牌对应的用户信息
        LoginUser loginUser = tokenService.getLoginUser(request);

        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
            //将 用户令牌对应在缓存中的 信息 进行刷新有效期（也就是续期）
            tokenService.verifyToken(loginUser);

            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());

            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }

        chain.doFilter(request, response);
    }
}
